# -*- coding:utf-8  -*-
# @Author: ChenYangMing
# @Time: 2024-08-29

import os
from concurrent.futures import ThreadPoolExecutor, as_completed
from multiprocessing import Pool


class ThreadUtils:
    """
    线程和进程工具类，提供并行处理的方法。
    包括使用线程池和进程池进行并行处理。
    """
    @staticmethod
    def parallel_process_with_futures(
            func,
            items,
            num_processes=None,
    ):
        """
        使用 concurrent.futures.ThreadPoolExecutor 执行并行处理
        :param func: 要并行执行的函数
        :param items: 要处理的项目列表
        :param num_processes: 使用的进程数，如果为 None，则使用 os.cpu_count()
        :return: 函数返回值的列表
        """
        if num_processes is None:
            num_processes = os.cpu_count()

        results = []
        with ThreadPoolExecutor(max_workers=num_processes) as executor:
            future_to_item = {executor.submit(func, item): item for item in items}
            for future in as_completed(future_to_item):
                item = future_to_item[future]
                try:
                    results.append(future.result())
                except Exception as e:
                    print(f"Item {item!r} raised an exception: {e}")
        return results

    @staticmethod
    def parallel_process_with_multiprocessing(
            func,
            items,
            num_processes=None,
    ):
        """
        使用 multiprocessing.Pool 执行并行处理
        :param func: 要并行执行的函数
        :param items: 要处理的项目列表
        :param num_processes: 使用的进程数，如果为 None，则使用 os.cpu_count()
        :return: 函数返回值的列表
        """
        if num_processes is None:
            num_processes = os.cpu_count()

        with Pool(processes=num_processes) as pool:
            results = pool.map(func, items)
            pool.close()
        return results


# 调用示例
# file_list = [...]
# partial_process = partial(func, func_args)  # 创建局部函数的偏函数
# # 使用 ThreadUtils 执行并行处理，方法一：使用 concurrent.futures
# results_with_futures = ThreadUtils.parallel_process_with_futures(
#     partial_process, file_list
# )
# # 使用 ThreadUtils 执行并行处理，方法二：使用 multiprocessing
# results_with_multiprocessing = ThreadUtils.parallel_process_with_multiprocessing(
#     partial_process, file_list
# )
# print("Results with futures:", results_with_futures)
# print("Results with multiprocessing:", results_with_multiprocessing)
